<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button>点击</button>
  <script>
    let o = {
      name: 'tom'
    }

    function fn() {
      console.log(this)
    }

    fn()  //此时什么都不加，this指向的是windows

    let o2 = {
      name: 'tom'
    }

    function fn2() {
      console.log(this)
    }
    // 使用bind方法之后，会改变this的指向
    let f2 = fn2.bind(o2)
    f2()

    let o3 = {
      name: 'tom'
    }

    function fn3(a, b) {
      console.log(this)
      console.log(a + b);
    }
    // 使用call方法之后，会改变this的指向
    let f3 = fn3.bind(o3, 1, 2)
    f3()

    // bind方法，可以配合构造函数使用
    function Student3(theName, theAge) {
      this.name = theName;
      this.age = theAge
    }
    var stu3 = { className: '112期' }
    var fnn = Student3.bind(stu3, '小红', 18)
    fnn()
    console.log(stu3);// {className: "112期", name: "小红", age: 18}

    // bind的应用 如果有的函数不需要立即执行，但是又需要改变这个函数的this指向，就可以使用bind
    // 有一个按钮，点击之后禁用它，3秒之后开启这个按钮

    let btn = document.querySelector('button')
    btn.onclick = function () {
      this.disabled = true

      // 第一种，直接使用this,不生效，因为这时this指向的是windows
      // 我们希望的是它指向btn
      // setTimeout(function () {
      //   this.disabled = false
      // }, 1000)

      // 第二种就是使用变量来做一个代替，也可以实现效果
      // let that = this
      // setTimeout(function () {
      //   that.disabled = false
      // }, 1000)

      // 第三种箭头函数也可以
      // setTimeout(() => {
      //   this.disabled = false
      // }, 1000)

      // 第四种使用bind
      setTimeout(function () {
        this.disabled = false
        //这里绑定的this指向的也是btn,因为它是在定时器函数（这里是一个匿名函数）
        // 的外面做的绑定，所以他指向的是btn,这样他就可以修改函数内部的this指向
      }.bind(this), 1000)
    }


    function Father(name, age, sex) {
      this.name = name
      this.age = age
      this.sex = sex
    }
    function Son(name, age, sex) {
      // 这里使用son中的this，替换father中的this
      let fn = Father.bind(this, name, age, sex)
      fn()
    }

    let son = new Son('tom', 18, '男')
    console.log(son);
  </script>
</body>

</html>